using System;
using System.Collections;
using System.Globalization;
using System.Xml;

using Oxbow.Tools;
using uk.co.aspellclark.common.ipaq;

namespace uk.co.aspellclark.todolistppc
{
    /// <summary>
    ///   <name>CTask</name>
    ///   <namespace>Arcsoft.ToDoListPPC</namespace>
    ///   <version>1.0</version>
    ///   <author>Andy Aspell-Clark</author>
    ///   <description>
    ///   </description>
    ///   <history>
    ///     <historyitem> 1 Aug 2004  1.0 ARA  Initial Version.</historyitem>
    ///   </history>
    /// </summary>
    public class CTask
    {
        #region Member variables

        private Int16    m_iRisk = 0;
        private Int16    m_iTaskId = 0;
        private Int16    m_iParentTaskId = 0;
        private Int16    m_iPriority = 5;
        private Int16    m_iPosition = 0;
        private Single   m_sngHoursEst = 0;
        private Int16    m_iPercentComplete = 0;
        private string   m_strAllocatedTo = null;
        private string   m_strAllocatedBy = null;

		private string   m_strPriorityColor = null;
		private string   m_strPriorityWebColor = null;
        
        private DateTime m_dtStartDate;
        private string   m_strStartDate = null;
        
        private DateTime m_dtCreationDate;
        private string   m_strCreationDate = null;
        
        private DateTime m_dtDueDate;
        private string   m_strDueDate = null;
        private DateTime m_dtDoneDate;
        private string   m_strDoneDate = null;
        //private string   m_sTimeSpentUnits = "H";
        //private string   m_sTimeEstUnits = "H";
        private DateTime m_dtLastMod = DateTime.Now;
        private string   m_strLastMod = null;

        private string   m_sCategory = null;
        private string   m_sStatus = null;
        private string   m_sFileRefPath = null;
        private string   m_sColour = null;
        private string   m_sWebColour = null;
        private string   m_strTitle = null;

        private string   m_sTimeESpentUnits = null;
        private bool     m_bComplete = false;
        
        private string   m_strNotes = null;
        private string   m_sRTFComments = "";

        
        private ArrayList StoreAsIs = new ArrayList(20);
        
        // stuff to handle locale settings, primairly differences between dot and comma in numbers (yes, Convert.toDouble 2 param would have worked too;-)
        private static CultureInfo Invc = CultureInfo.InvariantCulture;  //InvariantCulture is the neutral culture
        private static NumberFormatInfo nfi = (NumberFormatInfo)Invc.GetFormat(typeof(System.Globalization.NumberFormatInfo));
        private static DateTimeFormatInfo dfi = (DateTimeFormatInfo)Invc.GetFormat(typeof(System.Globalization.DateTimeFormatInfo));

        #endregion


        #region Properties

        /// <summary>
        /// 
        /// </summary>
        public DateTime CreationDate
        {
        	get { return m_dtCreationDate;  }
        	set { m_dtCreationDate = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string CreationDateStr
        {
        	get { return m_strCreationDate;  }
        	set { m_strCreationDate = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public Int16 Risk
        {
        	get { return m_iRisk;  }
        	set { m_iRisk = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string PriorityColor
        {
        	get { return m_strPriorityColor;  }
        	set { m_strPriorityColor = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string PriorityWebColor
        {
        	get { return m_strPriorityWebColor;  }
        	set { m_strPriorityWebColor = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public String Notes {
            get { return m_strNotes; }
            set { m_strNotes = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string RtfComments
        {
        	get { return m_sRTFComments;  }
        	set { m_sRTFComments = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public Int16 TaskId
        {
            get { return m_iTaskId; }
            set
            {
                if(value >= 0 && value <= 16384)
                {
                    m_iTaskId = value;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Int16 ParentTaskId
        {
            get { return m_iParentTaskId; }
            set
            {
                if(value >= 0 && value <= 16384)
                {
                    m_iParentTaskId = value;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Int16 Priority
        {
            get { return m_iPriority; }
            set
            {
                if(value >= 0 && value <= 10)
                {
                    m_iPriority = value;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Int16 Position
        {
            get { return m_iPosition; }
            set
            {
                if(value >= 0 && value <= 100)
                {
                    m_iPosition = value;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Single HoursEst
        {
            get { return m_sngHoursEst;  }
            set { m_sngHoursEst = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public Int16 PercentComplete
        {
            get { return m_iPercentComplete; }
            set
            {
                if(value >= 0 && value <= 100)
                {
                    m_iPercentComplete = value;
                    if (value == 100) { m_bComplete = true; } 
                    else {m_bComplete = false;}
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public Boolean Complete
        {
            get { return m_bComplete;  }
            set 
            {
                m_bComplete = value;
                if (value == true) { m_iPercentComplete = 100; } 
                else {m_iPercentComplete = 0;}
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string AllocatedTo
        {
            get { return m_strAllocatedTo;  }
            set { m_strAllocatedTo = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public string AllocatedBy
        {
            get { return m_strAllocatedBy;  }
            set { m_strAllocatedBy = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public DateTime StartDate
        {
            get { return m_dtStartDate; }
            set { m_dtStartDate = value; m_strStartDate = FormatDateString(value.ToString("yyyy-mm-dd")); }
        }
        /// <summary>
        /// 
        /// </summary>
        public string StartDateStr
        {
            get { return m_dtStartDate.ToString("yyyy-mm-dd"); }
        }

        /// <summary>
        /// 
        /// </summary>
        public DateTime DueDate
        {
            get { return m_dtDueDate; }
            set { m_dtDueDate = value; m_strDueDate = FormatDateString(value.ToString("yyyy-mm-dd")); }
        }
        /// <summary>
        /// 
        /// </summary>
        public string DueDateStr
        {
            get { return m_dtDueDate.ToString("yyyy-mm-dd"); }
        }

        /// <summary>
        /// 
        /// </summary>
        public DateTime DoneDate
        {
            get { return m_dtDoneDate; }
            set { m_dtDoneDate = value; m_strDoneDate = FormatDateString(value.ToString("yyyy-mm-dd")); }
        }
        /// <summary>
        /// 
        /// </summary>
        public string DoneDateStr
        {
            get { return m_dtDoneDate.ToString("yyyy-mm-dd"); }
        }

        /// <summary>
        /// 
        /// </summary>
        public string LastModStr
        {
            get { return m_strLastMod; }
            set { m_strLastMod = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public DateTime LastMod
        {
            get { return m_dtLastMod; }
            set { m_dtLastMod = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string Status
        {
            get { return m_sStatus;  }
            set { m_sStatus = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string FileRefPath
        {
            get { return m_sFileRefPath;  }
            set { m_sFileRefPath = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string Colour
        {
            get { return m_sColour;  }
            set { m_sColour = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string WebColour
        {
            get { return m_sWebColour;  }
            set { m_sWebColour = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public string TimeESpentUnits
        {
            get { return m_sTimeESpentUnits;  }
            set { m_sTimeESpentUnits = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public string Title
        {
            get { return m_strTitle;  }
            set { m_strTitle = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public string Category
        {
            get { return m_sCategory;  }
            set { m_sCategory = value; }
        }


        #endregion



        private void DisplayMsg(string aMsg)
        {
			TextLogger.Log( " CTask(): " + aMsg );
        }
        
        private string FormatDateString(string strDate)
        {
            string strReturn;

            try
            {
                strReturn = Convert.ToDateTime(strDate).ToString("MM/dd/yyyy");
            }
            catch
            {
                strReturn = strDate;
            }

            return strReturn;
        }

        
        /// <summary>
        /// Reads in this tasks properties from the xml node
        /// </summary>
        /// <param name="xndTask"></param>
        public void readFromXml(XmlNode xndTask)
        {
            foreach (XmlNode node in xndTask.Attributes)
            {
                if (node.InnerText.Length <= 0) continue;
                switch (node.Name) {
                    // only items we actually handle get a case of their own, all others are
                    // stuffed into an ArrayList only to be used by writeToXml
                    case "TITLE": {
                            Title = node.InnerText;
                            //Debug.WriteLine("readin taskFromXml Title=" + Title);
                            break;
                        }
                    case "PRIORITY": {
                            Priority = Convert.ToInt16(node.InnerText);
                            break;
                        }
                    case "CUSTOMCOMMENTS": {
                            RtfComments = node.InnerText;
                            break;
                        }
                    case "PERCENTDONE": {
                            PercentComplete = Convert.ToInt16(node.InnerText);
                            break;
                        }
                    case "STARTDATE": {
                            try {
                                StartDate = CommonFunctions.OleDateToDateTime(double.Parse(node.InnerText, nfi));
                            } catch (Exception e) {
                                throw new Exception(e.Message + " STARTDATE " + Title + "Orig: " + node.InnerText);
                            }
                            break;
                        }
                    case "DUEDATE": {
                            try {
                                DueDate = CommonFunctions.OleDateToDateTime(double.Parse(node.InnerText, nfi));
                            } catch (Exception e) {
                                throw new Exception(e.Message + " DUEDATE " + Title + " Orig:" + node.InnerText);
                            }
                            break;
                        }
                    case "DONEDATE": {
                            try {
                                DoneDate = CommonFunctions.OleDateToDateTime(double.Parse(node.InnerText, nfi));
                            } catch (ArgumentException e) {
                                throw new Exception(e.Message + " DONEDATE " + Title + " Orig:" + node.InnerText);
                            }

                            break;
                        }
                    case "PERSON": {
                            AllocatedTo = node.InnerText;
                            break;
                        }
                    case "ALLOCBY": {
                            AllocatedBy = node.InnerText;
                            break;
                        }
                    case "STATUS": {
                            Status = node.InnerText;
                            break;
                        }
                    case "TIMEESTIMATE":
                    {
                            HoursEst = Convert.ToSingle(node.InnerText);
                            break;
                        }
                    case "COMMENTS":
                    {
                            Notes = node.InnerText;
                            break;
                        }
                    case "POS":
                    {
                            Position = Convert.ToInt16(node.InnerText);
                            break;
                        }
                    case "ID":
                    {
                            TaskId = Convert.ToInt16(node.InnerText);
                            break;
                        }
                    default:
                    {
                		// ugly as heck, what are those calculated *STRING fields doing in the file in the first place?
                        // must ask Dan one day --Frans
                        if (!node.Name.EndsWith("STRING"))
                        {
                            StoreAsIs.Add(node);
                        	TextLogger.Log("Stored as Is: element " + node.Name.ToLower() );
                        }
                        break;
                    }
                }//switch()
            }

            if (PercentComplete == 100)
            {
                Complete = true;
            }
        }//readFromXml()




        /// <summary>
        /// 
        /// </summary>
        /// <param name="xmlWriter"></param>
        public void writeToXml(XmlTextWriter xmlWriter)
        {
            xmlWriter.WriteString("\n");
            xmlWriter.WriteStartElement("TASK");

            xmlWriter.WriteAttributeString("", "PRIORITY", "", m_iPriority.ToString());
            if (Status != "") {
                xmlWriter.WriteAttributeString("", "STATUS", "", Status);
            }
            xmlWriter.WriteAttributeString("", "TITLE", "", Title);
            if (AllocatedTo != "") {
                xmlWriter.WriteAttributeString("", "PERSON", "", AllocatedTo);
            }
            xmlWriter.WriteAttributeString("", "ID", "", m_iTaskId.ToString());
            if (m_strStartDate != null) {
                xmlWriter.WriteAttributeString("", "STARTDATESTRING", "", StartDate.ToString("yyyy-mm-dd"));
                xmlWriter.WriteAttributeString("", "STARTDATE", "",
                        CommonFunctions.DateTimeToOleDate(StartDate).ToString());
            }
            if (Position > 0) {
                xmlWriter.WriteAttributeString("", "POS", "", Position.ToString());
            }
            if (HoursEst > -1) {
                xmlWriter.WriteAttributeString("", "TIMEESTIMATE", "", HoursEst.ToString());
            }
            if (PercentComplete > -1) {
                xmlWriter.WriteAttributeString("", "PERCENTDONE", "", PercentComplete.ToString());
            }
            if (m_strDueDate != null) {
                xmlWriter.WriteAttributeString("", "DUEDATESTRING", "", DueDate.ToString("yyyy-mm-dd"));
                xmlWriter.WriteAttributeString("", "DUEDATE", "",
                    CommonFunctions.DateTimeToOleDate(DueDate).ToString());
            }
            if (m_strDoneDate != null) {
                xmlWriter.WriteAttributeString("", "DONEDATESTRING", "", DoneDate.ToString("yyyy-mm-dd"));
                xmlWriter.WriteAttributeString("", "DONEDATE", "",
                    CommonFunctions.DateTimeToOleDate(DoneDate).ToString());
            }
            if (RtfComments != "") {
                xmlWriter.WriteAttributeString("", "CUSTOMCOMMENTS", "", RtfComments);
            }
            if (Notes != "") {
                xmlWriter.WriteAttributeString("", "COMMENTS", "", Notes);
            }

            // write the elements we did read but do not touch or handle in this program itself
            foreach (XmlNode node in StoreAsIs) {
                xmlWriter.WriteAttributeString("", node.Name.ToUpper(), "", node.InnerText);
            }

        }

        /// <summary>
        /// 
        /// </summary>
        public void endWriteToXml(XmlTextWriter xmlWriter)
        {
            xmlWriter.WriteEndElement();
        }
    }//class()
}//namespace()
